vulkan: Add support for color matrix nodes
authorBenjamin Otte <otte@redhat.com>
Sat, 31 Dec 2016 13:14:26 +0000 (14:14 +0100)
committerBenjamin Otte <otte@redhat.com>
Sat, 31 Dec 2016 13:37:20 +0000 (14:37 +0100)
@keyframes weee {
    100% { filter: hue-rotate(1turn); }
}

.background {
    animation: linear infinite 3s weee;
}

gsk/gskvulkanrenderpass.c

index b005607423fb3ccb1174e6b7e83ded7e33c2660e..b9136bce4ec84986beb0ff17b32dcfefafb81b2c 100644 (file)
@@ -29,6 +29,7 @@ typedef enum {
   GSK_VULKAN_OP_COLOR,
   GSK_VULKAN_OP_LINEAR_GRADIENT,
   GSK_VULKAN_OP_OPACITY,
+  GSK_VULKAN_OP_COLOR_MATRIX,
   /* GskVulkanOpPushConstants */
   GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS
 } GskVulkanOpType;
@@ -183,6 +184,20 @@ gsk_vulkan_render_pass_add_node (GskVulkanRenderPass           *self,
       g_array_append_val (self->render_ops, op);
       return;
 
+    case GSK_COLOR_MATRIX_NODE:
+      if (gsk_vulkan_clip_contains_rect (&constants->clip, &node->bounds))
+        pipeline_type = GSK_VULKAN_PIPELINE_COLOR_MATRIX;
+      else if (constants->clip.type == GSK_VULKAN_CLIP_RECT)
+        pipeline_type = GSK_VULKAN_PIPELINE_COLOR_MATRIX_CLIP;
+      else if (constants->clip.type == GSK_VULKAN_CLIP_ROUNDED_CIRCULAR)
+        pipeline_type = GSK_VULKAN_PIPELINE_COLOR_MATRIX_CLIP_ROUNDED;
+      else
+        FALLBACK ("Color matrix nodes can't deal with clip type %u\n", constants->clip.type);
+      op.type = GSK_VULKAN_OP_COLOR_MATRIX;
+      op.render.pipeline = gsk_vulkan_render_get_pipeline (render, pipeline_type);
+      g_array_append_val (self->render_ops, op);
+      return;
+
     case GSK_CONTAINER_NODE:
       {
         guint i;
@@ -437,6 +452,18 @@ gsk_vulkan_render_pass_upload (GskVulkanRenderPass  *self,
           }
           break;
 
+        case GSK_VULKAN_OP_COLOR_MATRIX:
+          {
+            GskRenderNode *child = gsk_color_matrix_node_get_child (op->render.node);
+
+            op->render.source = gsk_vulkan_render_pass_get_node_as_texture (self, 
+                                                                            render,
+                                                                            uploader,
+                                                                            child,
+                                                                            &child->bounds);
+          }
+          break;
+
         default:
           g_assert_not_reached ();
         case GSK_VULKAN_OP_COLOR:
@@ -481,6 +508,7 @@ gsk_vulkan_render_pass_count_vertex_data (GskVulkanRenderPass *self)
           break;
 
         case GSK_VULKAN_OP_OPACITY:
+        case GSK_VULKAN_OP_COLOR_MATRIX:
           op->render.vertex_count = gsk_vulkan_effect_pipeline_count_vertex_data (GSK_VULKAN_EFFECT_PIPELINE (op->render.pipeline));
           n_bytes += op->render.vertex_count;
           break;
@@ -574,6 +602,17 @@ gsk_vulkan_render_pass_collect_vertex_data (GskVulkanRenderPass *self,
           }
           break;
 
+        case GSK_VULKAN_OP_COLOR_MATRIX:
+          {
+            op->render.vertex_offset = offset + n_bytes;
+            gsk_vulkan_effect_pipeline_collect_vertex_data (GSK_VULKAN_EFFECT_PIPELINE (op->render.pipeline),
+                                                            data + n_bytes + offset,
+                                                            &op->render.node->bounds,
+                                                            gsk_color_matrix_node_peek_color_matrix (op->render.node),
+                                                            gsk_color_matrix_node_peek_color_offset (op->render.node));
+            n_bytes += op->render.vertex_count;
+          }
+          break;
 
         default:
           g_assert_not_reached ();
@@ -606,6 +645,7 @@ gsk_vulkan_render_pass_reserve_descriptor_sets (GskVulkanRenderPass *self,
         case GSK_VULKAN_OP_SURFACE:
         case GSK_VULKAN_OP_TEXTURE:
         case GSK_VULKAN_OP_OPACITY:
+        case GSK_VULKAN_OP_COLOR_MATRIX:
           op->render.descriptor_set_index = gsk_vulkan_render_reserve_descriptor_set (render, op->render.source);
           break;
 
@@ -676,6 +716,7 @@ gsk_vulkan_render_pass_draw (GskVulkanRenderPass     *self,
           break;
 
         case GSK_VULKAN_OP_OPACITY:
+        case GSK_VULKAN_OP_COLOR_MATRIX:
           if (current_pipeline != op->render.pipeline)
             {
               current_pipeline = op->render.pipeline;